/*
 * lhVxbFslFpag.h
 *
 *  Created on: Sep 24, 2019
 *      Author: dubingwei
 */

#ifndef DRIVER_AXI_FPGA_LHVXBFSLFPAG_H_
#define DRIVER_AXI_FPGA_LHVXBFSLFPAG_H_
#ifdef __cplusplus
extern "C" {
#endif

#define AXI_FPGA_NAME 			"axiFpgaDrv"
#define AXI_FPGA_UNIT 			(0)
 

typedef struct fpga_drv_ctrl
{
    VXB_DEV_ID  	pDev;
    void *     		fpgaBar;				/*fpga 控制器寄存器bar*/
    void *     		fpgaHandle; 			/*fpga 控制器句柄*/
  
    SEM_ID          fpgaSem;
    
	VIRT_ADDR       fpgaVirBar;				/*用户数据存放虚拟基地址*/	
	PHYS_ADDR       fpgaPhyBar;				/*用户数据存放物理基地址*/
    
	VXB_RESOURCE *      intRes;
} FPGA_DRV_CTRL;
    
/* 时间日期结构体 */
typedef struct time_date {
    UINT8   second;     /* 秒 (0-59) */
    UINT8   minute;     /* 分 (0-59) */
    UINT8   hour;       /* 时 (0-23) */
    UINT8   day;        /* 日 (1-31) */
    UINT8   month;      /* 月 (1-12) */
    UINT16  year;       /* 年 (e.g., 2025) */
} TIME_DATE;



#define FPGA_BAR(pDev)      (((FPGA_DRV_CTRL *)vxbDevSoftcGet(pDev))->fpgaBar)
#define FPGA_HANDLE(pDev)   (((FPGA_DRV_CTRL *)vxbDevSoftcGet(pDev))->fpgaHandle)

#define AXI_BAR(pDev)      (((FPGA_DRV_CTRL *)vxbDevSoftcGet(pDev))->axiBar)
#define AXI_HANDLE(pDev)   (((FPGA_DRV_CTRL *)vxbDevSoftcGet(pDev))->axiHandle)

// 各模块基地址（十六进制）
#define AXILITE2AXIS_BASE        0x00000  // 寄存器读写模块
#define AXI_IO_INTR_BASE         0x10000  // 中断控制器（文档第7部分明确基地址）
#define HEIR_SAM0_4_BASE         0x80000  // 组0~4控制模块
#define HEIR_SAM5_9_BASE         0x90000  // 组5~9控制模块
#define HEIR_SAM10_14_BASE       0xA0000  // 组10~14控制模块
#define HEIR_SAM15_19_BASE       0xB0000  // 组15~19控制模块

 
 
#define AXILITE2AXIS_LOGIC_TIME    	0x00
#define AXILITE2AXIS_LOGIC_DATE   	0x04
// 组采集使能（读写）
#define AXILITE2AXIS_GROUP_EN     	0x10

// 组采集使能位定义（n=0~19）
#define GROUP_EN(n)               (1 << (n))  // 置1：使能组n；置0：关闭组n


// 辅助宏：获取全局组n所在模块的基地址（n=0~19）
#define GET_GROUP_BASE(n)  \
    (((n) >= 0 && (n) <= 4) ? HEIR_SAM0_4_BASE : \
     ((n) >= 5 && (n) <= 9) ? HEIR_SAM5_9_BASE : \
     ((n) >= 10 && (n) <= 14) ? HEIR_SAM10_14_BASE : \
     ((n) >= 15 && (n) <= 19) ? HEIR_SAM15_19_BASE : 0)

// 辅助宏：获取组n在模块内的序号（0~4）
#define GET_MODULE_GROUP(n)  \
    ((n) >= 0 && (n) <= 4 ? (n) : \
     (n) >= 5 && (n) <= 9 ? (n) - 5 : \
     (n) >= 10 && (n) <= 14 ? (n) - 10 : \
     (n) >= 15 && (n) <= 19 ? (n) - 15 : 0)

// 组n控制寄存器（读写）
#define HEIR_SAM_CTRL_REG(n)    	(GET_GROUP_BASE(n) + (GET_MODULE_GROUP(n) * 0x20) + 0x00)
// 组n采样时长（读写）
#define HEIR_SAM_SAMPLE_DUR(n)  	(GET_GROUP_BASE(n) + (GET_MODULE_GROUP(n) * 0x20) + 0x04)
// 组n数据存储地址（读写）
#define HEIR_SAM_DATA_ADDR(n)   	(GET_GROUP_BASE(n) + (GET_MODULE_GROUP(n) * 0x20) + 0x08)
// 组n采集完成次数（只读）
#define HEIR_SAM_COMPLETE_CNT(n)	(GET_GROUP_BASE(n) + (GET_MODULE_GROUP(n) * 0x20) + 0x10)
// 组n采集长度（只读）
#define HEIR_SAM_LENGTH(n)      	(GET_GROUP_BASE(n) + (GET_MODULE_GROUP(n) * 0x20) + 0x14)
// 组n缓存溢出次数（只读）
#define HEIR_SAM_OVERFLOW_CNT(n)	(GET_GROUP_BASE(n) + (GET_MODULE_GROUP(n) * 0x20) + 0x18)



// 控制寄存器位定义
#define CTRL_EN         (1 << 0)   // 采集使能（1=使能）
#define CTRL_EDGE_EN    (1 << 1)   // 边沿使能（1=使能）
#define CTRL_EDGE_RISE  (1 << 2)   // 沿类型（1=上升沿，0=下降沿）
#define CTRL_SELF_TEST	(1 << 3)
#define CTRL_EDGE_PIN(sel) ((sel & 0x0F) << 4)  // 沿同步管脚选择（sel=0~11）


// 中断控制寄存器定义
#define FPGA_RESET_REG         0x10000   // 复位寄存器
#define FPGA_TEST_INT_REG      0x10004   // 测试中断寄存器
#define FPGA_INT_STATUS_REG    0x10008   // 中断状态/清除寄存器
#define FPGA_INT_ENABLE_REG    0x1000C   // 中断使能寄存器
#define FPGA_INT_TYPE_REG      0x10010   // 中断类型寄存器
#define FPGA_INT_POLARITY_REG  0x10014   // 中断极性寄存器
#define FPGA_OUTPUT_LEVEL_REG  0x10018   // 输出电平寄存器
#define FPGA_PULSE_WIDTH_REG   0x1001C   // 输出脉宽寄存器
#define FPGA_GLOBAL_ENABLE_REG 0x10024   // 全局中断使能寄存器
#define FPGA_EDGE_DETECT_REG   0x10028   // 边沿触发寄存器

// 复位寄存器值
#define FPGA_RESET_VALUE       0xA    // 写入0xA时复位

// 寄存器位定义
#define FPGA_INT_BIT(n)        (1U << (n))  // 第n位中断控制位

// 中断类型
#define FPGA_INT_TYPE_LEVEL    1      // 电平触发
#define FPGA_INT_TYPE_EDGE     0      // 边沿触发

// 中断极性
#define FPGA_INT_POL_RISING    1      // 上升沿/高电平触发
#define FPGA_INT_POL_FALLING   0      // 下降沿/低电平触发

// 输出电平
#define FPGA_OUT_LOW_IDLE      0      // 空闲低电平，中断高电平
#define FPGA_OUT_HIGH_IDLE     1      // 空闲高电平，中断低电平

// 全局中断使能
#define FPGA_GLOBAL_INT_ENABLE 0x1    // 全局中断使能位

#undef CSR_READ_4
#define CSR_READ_4(pDev, addr)                                  \
    vxbRead32 (FPGA_HANDLE(pDev), (UINT32 *)((char *)FPGA_BAR(pDev)+((UINT32)(addr))))

#undef CSR_WRITE_4
#define CSR_WRITE_4(pDev, addr, data)                           \
    vxbWrite32 (FPGA_HANDLE(pDev),                             \
        (UINT32 *)((char *)FPGA_BAR(pDev)+((UINT32)(addr))), data)

// 函数声明
void axiFpgaOpen(VXB_DEV_ID * ppDev, UINT32 unit);
int axiFpgaClose(VXB_DEV_ID pDev);
UINT32 axiFpgaGet(VXB_DEV_ID pDev, UINT32 offset);
void axiFpgaSet(VXB_DEV_ID pDev, UINT32 offset, UINT32 val);
UINT32 ddRegGet(UINT32 offset);
void ddRegSet(UINT32 offset, UINT32 val);
STATUS timeDateGet(TIME_DATE *pTimeDate);
STATUS timeDateShow(void);
unsigned int get_fpga_slot_number(void);
void test_slot_number(void);
void syncControlAllGroups(unsigned char enable);
void enable_group(unsigned char group, unsigned char enable);
unsigned char is_group_enabled(unsigned char group);
unsigned char is_group_finish(unsigned char group);
void clear_group_state(unsigned char group);
void set_sample_duration(unsigned char group, unsigned int sample_duration);
void select_data_source(unsigned char group, unsigned char use_test_data);
void config_edge_trigger(unsigned char group, unsigned char edge_pin, unsigned char enable, unsigned char rise_fall);
void config_self_test(unsigned char group, unsigned char enable);
void config_sample_dur(unsigned char group, unsigned int duration);
void set_buffer_address(unsigned char group, unsigned int buffer_addr);
unsigned int get_complete_count(unsigned char group);
unsigned int get_data_length(unsigned char group);
void clear_interrupt(unsigned char group);
void printInterruptStatus(void);
void enable_interrupt(unsigned char group);
void print_group_info(unsigned char group);
 
 
#ifdef __cplusplus
}
#endif

#endif /* DRIVER_AXI_FPGA_LHVXBFSLFPAG_H_ */
